package com.northwest_man.refactor_tool;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MergeStringXmlFile {

    private static final String root = "/home/r/AndroidStudioProjects/patpat/Patpat/src/main/res/values-it";
    private static final String regex = "(?<!-)" + Constants.STRING_ITEM_ROW_REGEX;

    public static void main(String[] args) throws IOException {
        final String addFileContent = FileUtils.readFileToString(new File(root + "/it.txt"));
        final String oldFileContent = FileUtils.readFileToString(new File(root + "/strings.xml"));
        final List<KV> newList = new ArrayList<>();
        final List<KV> oldList = new ArrayList<>();
        final Pattern pattern = Pattern.compile(regex);
        final Matcher oldMatcher = pattern.matcher(oldFileContent);
        final Matcher newMatcher = pattern.matcher(addFileContent);
        while (oldMatcher.find()) {
            oldList.add(new KV(oldMatcher.group(1), oldMatcher.group(2)));
        }
        while (newMatcher.find()) {
            newList.add(new KV(newMatcher.group(1), newMatcher.group(2)));
        }
        final JsonArray jsArr = new JsonArray();
        final List<KV> sameList = new ArrayList<>();
        final List<KV> updateList = new ArrayList<>();
        final List<KV> addList = new ArrayList<>();
        final List<KV> removeList = new ArrayList<>();
        for (final KV _new : newList) {
            boolean found = false;
            for (final KV old : oldList) {
                if (_new.key.trim().equals(old.key.trim())) {
                    if (_new.value.trim().equals(old.value.trim())) {
                        sameList.add(_new);
                    } else {
                        final JsonObject jsObj = new JsonObject();
                        jsObj.addProperty("type", "key value: " + _new.key);
                        final JsonArray jsArr2 = new JsonArray();
                        jsArr2.add(_new.value);
                        jsArr2.add(old.value);
                        jsObj.add("both", jsArr2);
                        jsArr.add(jsObj);
                        updateList.add(_new);
                    }
                    found = true;
                    break;
                } /*else if (_new.value.trim().equals(old.value.trim())) {
                    found=true;
                    final JsonObject jsObj = new JsonObject();
                    jsObj.addProperty("type", "same value: "+_new.value);
                    final JsonArray jsArr2 = new JsonArray();
                    jsArr2.add(_new.key);
                    jsArr2.add(old.key);
                    jsObj.add("both", jsArr2);
                    jsArr.add(jsObj);
                    break;
                }*/
            }
            if (!found) {
                addList.add(_new);
                jsArr.add("add key: " + _new.key + ", value: " + _new.value);
            }
        }
        for (final KV old : oldList) {
            boolean found = false;
            for (final KV _new : newList) {
                if (old.key.trim().equals(_new.key.trim())) {
                    found = true;
                    break;
                }
            }
            if (!found) removeList.add(old);
        }
        final List<KV> allList = new ArrayList<>();
        allList.addAll(sameList);
        allList.addAll(updateList);
        allList.addAll(addList);
        allList.addAll(removeList);
        Collections.sort(allList, (o1, o2) -> {
            final char[] charArr = o1.key.toCharArray();
            final char[] charArr2 = o2.key.toCharArray();
            final int size = charArr.length;
            final int size2 = charArr2.length;
            final int minSize = Math.min(size, size2);
            for (int i = 0; i < minSize; i++) {
                final char c = charArr[i];
                final char c1 = charArr2[i];
                final int sort = compareChar(c, c1);
                if (sort != 0) return sort;
            }

            return size - size2;
        });
        final StringBuilder result = new StringBuilder();
        result.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<resources>");
        for (final KV item : allList) {
            result.append(" <string name=\"").append(item.key).append("\">")
                    .append(item.value).append("</string>\n");
        }
        result.append("</resources>");
        System.out.println(result);
    }

    private static int compareChar(char a, char b) {
        final int sort = ProcessImpl.dodo(a);
        final int sort2 = ProcessImpl.dodo(b);

        return sort - sort2;
    }

    private static abstract class ProcessImpl {

        private ProcessImpl() {
        }

        public static int dodo(int character) {
            // 获取字符所在区间排序优先级
            // 95           _
            // [48, 57]     0-9
            // [97, 122]    a-z
            // [65, 90]     A-Z
            if (character == 95) {
                return 0;
            }
            for (int i = 48, j = 1; i <= 57; i++, j++) {
                if (character == i) return j;
            }


            for (int i = 97, j = 11; i <= 122; i++, j += 2) {
                if (character == i) return j;
            }
            for (int i = 65, j = 12; i <= 90; i++, j += 2) {
                if (character == i) return j;
            }
            return -1;


        }
    }

    private static class ComparePart {
        public final int bigPartResult;
        public final int smallPartResult;

        private ComparePart(int bigPartResult, int smallPartResult) {
            this.bigPartResult = bigPartResult;
            this.smallPartResult = smallPartResult;
        }
    }

    private static class KV {
        public final String key;
        public final String value;

        private KV(String key, String value) {
            this.key = key;
            this.value = value;
        }
    }
}
